package server;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.Image;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.text.DefaultCaret;

import java.awt.event.*;
import java.awt.image.BufferedImage;

import java.io.*;
import java.net.URL;
import java.text.*;
import java.util.*;

/**
 * @author Elliot Triplett
 *
 */
public class ServerGUI extends JFrame implements ActionListener{

	/**
	 * 
	 */
	private static final long serialVersionUID = -7975841830997707030L;
	private JFrame frmEspServerApplication;
	private JTextField ipField;
	private JTextArea taLog = new JTextArea();
	private JScrollPane scrollPane = new JScrollPane();

	private JTextField portField;
	private JTextField sendField;
	private JButton btnSend;
	private Server server;
	private LocalNode localNode;
	private ConnectionListener connectionListener;
	private boolean connectionStatus = false;
	private int [] lv = {0,0,0,0};

	private JButton btnConnect;
	private JButton btnSetUID;
	private JButton btnSetLC;
	private JButton btnSetLS;
	private JButton btnIncrLC;
	private JButton btnDecrLC;
	private JButton btnRefresh;

	private String ipText = "137.48.181.66";
	private JPanel pnlStatus;
	private JTextField txtStatus;
	private JTextField textLotID;
	private JTextField UIDField;
	private JTextField textLoop1;
	private JTextField textLoop2;
	private JTextField textLoop3;
	private JTextField textLoop4;
	private JTextField textTemp;
	private JTextField lotCountField;
	private JTextField lotSizeField;
	
	private Image pCampusIMG;


	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ServerGUI window = new ServerGUI();
					window.frmEspServerApplication.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public ServerGUI() {
		try {
			initialize();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Initialize the contents of the frame.
	 * @throws IOException 
	 */
	private void initialize() throws IOException {
		//This sets up the application window (JFRAME)
		String path = new java.io.File(".").getCanonicalPath();
		URL url = new URL("file:\\"+path+"\\imgs\\pcampus.png");
		this.pCampusIMG = ImageIO.read(url);
		frmEspServerApplication = new JFrame();
		frmEspServerApplication.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmEspServerApplication.setTitle("ESP Server Application");
		frmEspServerApplication.setBounds(100, 100, 600, 325);
		frmEspServerApplication.getContentPane().setLayout(null);

		JTabbedPane tabPane = new JTabbedPane(JTabbedPane.TOP);
		tabPane.setBounds(10, 11, 564, 240);
		frmEspServerApplication.getContentPane().add(tabPane);

		JPanel pnlMain = new JPanel();
		tabPane.addTab("Main Tab", null, pnlMain, null);

		//Adds the port text field
		ipField = new JTextField();
		//TODO set ip field correctly
		ipField.setText(ipText);
		ipField.setBounds(41, 11, 108, 20);
		ipField.setColumns(10);
		pnlMain.setLayout(null);

		//Adds the Labeling for the Port field
		JLabel lblIp = new JLabel("IP");
		lblIp.setHorizontalAlignment(SwingConstants.RIGHT);
		lblIp.setBounds(10, 14, 21, 14);
		pnlMain.add(lblIp);
		pnlMain.add(ipField);

		//Adds the Start Button
		btnConnect = new JButton("Connect");
		btnConnect.setToolTipText("Starts the server");
		btnConnect.addActionListener(this); 
		btnConnect.setBounds(259, 10, 108, 23);
		pnlMain.add(btnConnect);

		JLabel lblPort = new JLabel("Port");
		lblPort.setHorizontalAlignment(SwingConstants.RIGHT);
		lblPort.setBounds(159, 14, 30, 14);
		pnlMain.add(lblPort);

		portField = new JTextField();
		portField.setText("10001");
		portField.setColumns(10);
		portField.setBounds(199, 11, 50, 20);
		pnlMain.add(portField);

		pnlStatus = new JPanel();
		tabPane.addTab("Status", null, pnlStatus, null);
		pnlStatus.setLayout(null);

		JLabel lblConnectionStatus = new JLabel("Status:");
		lblConnectionStatus.setBounds(10, 9, 45, 14);
		pnlStatus.add(lblConnectionStatus);

		JLabel lblLotId = new JLabel("Lot ID:");
		lblLotId.setBounds(10, 32, 45, 14);
		pnlStatus.add(lblLotId);

		JLabel lblUid = new JLabel("UID:");
		lblUid.setBounds(10, 57, 45, 14);
		pnlStatus.add(lblUid);

		JLabel lblVoltages = new JLabel("Voltages");
		lblVoltages.setHorizontalAlignment(SwingConstants.CENTER);
		lblVoltages.setBounds(73, 77, 50, 14);
		pnlStatus.add(lblVoltages);

		JLabel label = new JLabel("Loop1:");
		label.setBounds(10, 96, 45, 14);
		pnlStatus.add(label);

		JLabel label_1 = new JLabel("Loop2:");
		label_1.setBounds(10, 118, 45, 14);
		pnlStatus.add(label_1);

		JLabel label_2 = new JLabel("Loop3:");
		label_2.setBounds(10, 140, 45, 14);
		pnlStatus.add(label_2);

		JLabel label_3 = new JLabel("Loop4:");
		label_3.setBounds(10, 162, 45, 14);
		pnlStatus.add(label_3);

		JLabel label_4 = new JLabel("Temp:");
		label_4.setBounds(10, 184, 45, 14);
		pnlStatus.add(label_4);

		txtStatus = new JTextField();
		txtStatus.setHorizontalAlignment(SwingConstants.CENTER);
		txtStatus.setText("Disconnected");
		txtStatus.setEditable(false);
		txtStatus.setBounds(55, 6, 86, 20);
		pnlStatus.add(txtStatus);
		txtStatus.setColumns(10);

		textLotID = new JTextField();
		textLotID.setEditable(false);
		textLotID.setHorizontalAlignment(SwingConstants.CENTER);
		textLotID.setColumns(10);
		textLotID.setBounds(55, 29, 86, 20);
		pnlStatus.add(textLotID);

		UIDField = new JTextField();
		UIDField.setHorizontalAlignment(SwingConstants.CENTER);
		UIDField.setColumns(10);
		UIDField.setBounds(55, 54, 86, 20);
		pnlStatus.add(UIDField);

		textLoop1 = new JTextField();
		textLoop1.setHorizontalAlignment(SwingConstants.CENTER);
		textLoop1.setEditable(false);
		textLoop1.setColumns(10);
		textLoop1.setBounds(55, 93, 86, 20);
		pnlStatus.add(textLoop1);

		textLoop2 = new JTextField();
		textLoop2.setHorizontalAlignment(SwingConstants.CENTER);
		textLoop2.setEditable(false);
		textLoop2.setColumns(10);
		textLoop2.setBounds(55, 115, 86, 20);
		pnlStatus.add(textLoop2);

		textLoop3 = new JTextField();
		textLoop3.setHorizontalAlignment(SwingConstants.CENTER);
		textLoop3.setEditable(false);
		textLoop3.setColumns(10);
		textLoop3.setBounds(55, 137, 86, 20);
		pnlStatus.add(textLoop3);

		textLoop4 = new JTextField();
		textLoop4.setHorizontalAlignment(SwingConstants.CENTER);
		textLoop4.setEditable(false);
		textLoop4.setColumns(10);
		textLoop4.setBounds(55, 159, 86, 20);
		pnlStatus.add(textLoop4);

		textTemp = new JTextField();
		textTemp.setHorizontalAlignment(SwingConstants.CENTER);
		textTemp.setEditable(false);
		textTemp.setColumns(10);
		textTemp.setBounds(55, 181, 86, 20);
		pnlStatus.add(textTemp);

		JLabel lblCounts = new JLabel("Counts");
		lblCounts.setHorizontalAlignment(SwingConstants.CENTER);
		lblCounts.setBounds(190, 77, 50, 14);
		pnlStatus.add(lblCounts);

		JLabel lblLotCount = new JLabel("Lot Count:");
		lblLotCount.setHorizontalAlignment(SwingConstants.TRAILING);
		lblLotCount.setBounds(151, 96, 70, 14);
		pnlStatus.add(lblLotCount);

		lotCountField = new JTextField();
		lotCountField.setColumns(10);
		lotCountField.setBounds(231, 93, 55, 20);
		pnlStatus.add(lotCountField);

		JLabel lblLotSize = new JLabel("Lot Size:");
		lblLotSize.setHorizontalAlignment(SwingConstants.TRAILING);
		lblLotSize.setBounds(151, 118, 70, 14);
		pnlStatus.add(lblLotSize);

		lotSizeField = new JTextField();
		lotSizeField.setColumns(10);
		lotSizeField.setBounds(231, 115, 55, 20);
		pnlStatus.add(lotSizeField);

		btnSetUID = new JButton("Set UID");
		btnSetUID.addActionListener(this);
		btnSetUID.setBounds(151, 53, 89, 23);
		pnlStatus.add(btnSetUID);

		btnSetLC = new JButton("Set");
		btnSetLC.addActionListener(this);
		btnSetLC.setToolTipText("Sets the lot count on the local node");
		btnSetLC.setBounds(296, 92, 89, 23);
		pnlStatus.add(btnSetLC);

		btnSetLS = new JButton("Set");
		btnSetLS.addActionListener(this);
		btnSetLS.setToolTipText("Sets the lot size for the local node");
		btnSetLS.setBounds(296, 114, 89, 23);
		pnlStatus.add(btnSetLS);

		btnIncrLC = new JButton("+");
		btnIncrLC.addActionListener(this);
		btnIncrLC.setBounds(395, 92, 45, 23);
		pnlStatus.add(btnIncrLC);

		btnDecrLC = new JButton("-");
		btnDecrLC.addActionListener(this);
		btnDecrLC.setBounds(450, 92, 45, 23);
		pnlStatus.add(btnDecrLC);

		btnRefresh = new JButton("Refresh");
		btnRefresh.addActionListener(this);
		btnRefresh.setBounds(151, 5, 89, 23);
		pnlStatus.add(btnRefresh);

		//Adds the log Panel
		JPanel pnlLog = new JPanel();
		pnlLog.setLayout(null);
		tabPane.addTab("Log", null, pnlLog, null);

		scrollPane = new JScrollPane();
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		scrollPane.setBounds(10, 11, 539, 201);
		pnlLog.add(scrollPane);
		taLog.setEditable(false);
		DefaultCaret caret = (DefaultCaret)taLog.getCaret();
		caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
		scrollPane.setViewportView(taLog);

		sendField = new JTextField();
		sendField.addActionListener(this);
		sendField.setBounds(92, 256, 482, 20);
		frmEspServerApplication.getContentPane().add(sendField);
		sendField.setColumns(10);

		btnSend = new JButton("Send");
		btnSend.addActionListener(this);
		btnSend.setBounds(10, 255, 72, 23);
		frmEspServerApplication.getContentPane().add(btnSend);
		
		localNode = new LocalNode('2',1,lv,0); //Creates the localNode TODO pull this from file...
		server = new Server(this, ipField.getText(),Integer.parseInt(portField.getText()), localNode);
		//Start the client connection listener...
		//connectionListener = new ConnectionListener(server);
		saveImage();
		
	}

	public void log(String msg){
		taLog.append(msg);
		writeToFile(msg);
	}

	@Override
	public void actionPerformed(ActionEvent a) {

		if (a.getSource() == btnConnect && (!connectionStatus)){
			try {
				server.setIP(ipField.getText(),Integer.parseInt(portField.getText()));
				server.connect();
				server.sendCmd(Command.REQ_STATUS);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		else if ( (a.getSource() == btnConnect) && connectionStatus){
			server.disconnect();
		}
		else if (connectionStatus){
			if ( (a.getSource() == sendField || a.getSource() == btnSend) && connectionStatus){
				server.sendMessage(sendField.getText());
				sendField.setText("");
			}
			if (a.getSource() == btnSetUID){
				server.sendCmd(Command.SET_UID, UIDField.getText());
			}
			if (a.getSource() == btnSetLC){
				server.sendCmd(Command.SET_LC, lotCountField.getText());
			}
			if (a.getSource() == btnSetLS){
				server.sendCmd(Command.SET_LS, lotSizeField.getText());
			}
			if (a.getSource() == btnIncrLC){
				server.sendCmd(Command.INCREMENT);
			}
			if (a.getSource() == btnDecrLC){
				server.sendCmd(Command.DECREMENT);
			}
			if (a.getSource() == btnRefresh){
				server.sendCmd(Command.REQ_STATUS);
			}
			refresh();
		}
	}

	public void refresh(){
		if (connectionStatus){
			//server.sendCmd(cmd)
			textLotID.setText(String.valueOf(localNode.getLotID()));
			UIDField.setText(String.valueOf(localNode.getUID()));
			textLoop1.setText(String.valueOf(localNode.getLoopVoltage(0)));
			textLoop2.setText(String.valueOf(localNode.getLoopVoltage(1)));
			textLoop3.setText(String.valueOf(localNode.getLoopVoltage(2)));
			textLoop4.setText(String.valueOf(localNode.getLoopVoltage(3)));
			textTemp.setText(String.valueOf(localNode.getTemp()));
			lotCountField.setText(String.valueOf(localNode.getLotCount()));
			lotSizeField.setText(String.valueOf(localNode.getLotSize()));
			
			if (localNode.getLoopVoltage(0) < 300){
				textLoop1.setBackground(Color.red);
			}
			else textLoop1.setBackground(Color.green);
			if (localNode.getLoopVoltage(1) < 300){
				textLoop2.setBackground(Color.red);
			}
			else textLoop2.setBackground(Color.green);
			if (localNode.getLoopVoltage(2) < 300){
				textLoop3.setBackground(Color.red);
			}
			else textLoop3.setBackground(Color.green);
			if (localNode.getLoopVoltage(3) < 300){
				textLoop4.setBackground(Color.red);
			}
			else textLoop4.setBackground(Color.green);
			if (localNode.getTemp() > 100){
				textTemp.setBackground(Color.red);
			}
			else textTemp.setBackground(Color.green);
			
		}
		this.repaint();

	}

	public void setConnectStatus(boolean connection) {
		if (connection){
			btnConnect.setText("Disconnect"); //switch to disconnect
			btnConnect.setToolTipText("Click to disconnect");
			txtStatus.setText("Connected");

		}
		else{
			btnConnect.setText("Connect"); //switch to disconnect
			btnConnect.setToolTipText("Starts the server");
			txtStatus.setText("Disconnected");
		}
		connectionStatus = connection;	
	}

	public void writeToFile(String str){

		Date date = new Date (System.currentTimeMillis());
		DateFormat df = new SimpleDateFormat("yyyyMMdd");
		df.setTimeZone(TimeZone.getTimeZone("CST"));
		String dateStr = df.format(date); //Gets the time stamp for the logging
		String path = "Lots\\"+localNode.getLotID()+"\\Logs\\";
		try {
			File file = new File(path);
			file.mkdirs();
			file = new File(path+dateStr+".log");
			if (!file.exists()){
				file.createNewFile(); //create a new file if this file doesn't exist
			}
			PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file,true)));
			String curTime = String.valueOf(System.currentTimeMillis());
			out.append("<"+curTime+">");
			out.append(str);
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}   
	}

	public void sendToClient() {
		String status = "[" + localNode.getLotID() + ":" + localNode.getLotCount() + ":" + localNode.getLotSize() + "]";
		connectionListener.sendToAll(status);
		
	}

	public void saveImage() {
		BufferedImage screen = new BufferedImage(pCampusIMG.getWidth(this), pCampusIMG.getHeight(this), BufferedImage.TYPE_INT_RGB);
		Graphics2D g = screen.createGraphics();
		g.drawImage( pCampusIMG, 0, 0, this );
		g.drawImage(localNode.getLotImage(connectionStatus),localNode.x,localNode.y,this);
		try {
				ImageIO.write(screen,"png", new File("C:\\www\\esparking\\scampus.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}
